본문으로 건너뛰기

<Suspense>

🧑🏻‍💻 Suspense


<Suspense>를 사용하면 자식이 로딩을 완료할 때까지 fallback을 표시할 수 있다.

✅ Suspense 문법

<Suspense fallback={<Loading />}>
<SomeComponent />
</Suspense>
  • children 컴포넌트들은 렌더링하려는 실제 UI 이다.
  • fallback은 로딩이 완료되지 않은 경우에 렌더링할 대체 UI이다.

🧑🏻‍💻 알고 가기


✅ 주요 특징

  • fallback 컴포넌트는 주로 로딩 스피너나 스켈레톤과 같은 가벼운 플레이스홀더 뷰를 사용한다.
  • <Suspense>children 컴포넌트가 일시 중단되면 자동으로 fallback으로 전환되고, 데이터가 준비되면 다시 children 컴포넌트로 전환된다.
  • React가 다시 일시 중단되어 이미 표시된 콘텐츠를 숨겨야 하는 경우, 콘텐츠 트리에서 layout Effect를 클린업하여, DOM 레이아웃을 측정하는 Effect가 동작하지 않도록 한다.

✅ 주의 사항

  • React는 처음 마운트하기 전에 일시 중단된 렌더링의 state를 보존하지 않는다. 따라서 <Suspense>가 트리에 대한 콘텐츠를 표시하고 있다가 일시 중단된 경우, 자식 컴포넌트의 로드가 다시 완료되면 렌더링도 처음부터 시도한다.
  • <Suspense>가 트리에 대한 콘텐츠를 표시하고 있다가 일시 중단된 경우, 그 원인이 startTransition이나 useDeferredValue가 아니라면 fallback이 다시 표시된다.
  • 업데이트 중에 UI가 Fallback으로 대체되는 것을 방지하려면 startTransition 을 사용하여 업데이트를 긴급하지 않은 것으로 표시해야 한다.

🧑🏻‍💻 활용 및 생각할 거리


✅ 중첩된 콘텐츠에 로드 화면 표시하기

import { Suspense } from 'react';
import Albums from './Albums.js';
import Biography from './Biography.js';
import Panel from './Panel.js';

export default function ArtistPage({ artist }) {
return (
<>
<h1>{artist.name}</h1>
<Suspense fallback={<BigSpinner />}>
<Biography artistId={artist.id} />
<Suspense fallback={<AlbumsGlimmer />}>
<Panel>
<Albums artistId={artist.id} />
</Panel>
</Suspense>
</Suspense>
</>
);
}

function BigSpinner() {
return <h2>🌀 Loading...</h2>;
}

function AlbumsGlimmer() {
return (
<div className="glimmer-panel">
<div className="glimmer-line" />
<div className="glimmer-line" />
<div className="glimmer-line" />
</div>
);
}
  • <Suspense> 안에 <Suspense>를 적용하여 구현 가능하다.
  • 이를 통해 UI의 어떤 부분이 동시에 ‘등장’해야 하는지, 어떤 부분이 점진적으로 콘텐츠를 표시해야 하는지 등을 조정할 수 있다.